package org.nobject.common.swing.g;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * GGridLayout
 *
 * @author bianrongjun
 * @version 1.0
 */
public class GGridLayout extends  GLayout {

	/** hgap */
	int hgap;
	/** vgap */
	int vgap;
	/** rows */
	int rownum;
	/** cols */
	int colnum;
	/** container */
	private Container container=null;
	
	/** 构造函数  @param container */
	public GGridLayout(Container container){
		this(container,5,5);
	}
	
	/** 构造函数  @param container */
	public GGridLayout(Container container,int hgap,int vgap){
		this.container=container;
		container.setLayout(this);
		this.hgap=hgap;
		this.vgap=vgap;
	}
	
	/** rows */
	private List rows=new LinkedList();
	
	/** 添加组件 */
	public GGridLayout append(Component c){
		if(container!=null) container.add(c);
		this.appendElement(c);
		return this;
	}
	
	/** 组件间距 */
	private int margin=5;
	
	/** margins */
	private Map margins=new HashMap();
	
	/** 添加组件 */
	public GGridLayout append(Component[] cs){
		return this.append(cs,5,AIGNMENT_CENTER);
	}
	
	/** 添加组件 */
	public GGridLayout append(Component[] cs,int margin,int alignment){
		if(cs!=null){
			for (int i = 0; i < cs.length; i++) {
				if(container!=null) container.add(cs[i]);
			}
			int[] rcIdx=this.appendElement(cs);
			margins.put(rcIdx[0]+","+rcIdx[1], margin);
			alignments.put(rcIdx[0]+","+rcIdx[1], alignment);
		}
		return this;
	}
	
	/** @param rowIdx @param colIdx @param margin */
	public void setMargin(int rowIdx,int colIdx,int margin){
		this.margins.put(rowIdx+","+colIdx, margin);
	}
	
	
	/** 换行 */
	public final static String NL="NL";
	
	/** 添加换行 */
	public GGridLayout appendNL(){
		this.appendElement(NL);
		return this;
	}
	
	/** 添加元素 @param o */
	private int[] appendElement(Object o){
		List operRow=null;
		List lastRow=null;
		int []rcIdx=new int[2];
		if(rows.size()==0) lastRow=new LinkedList();
		else lastRow=(List)rows.get(rows.size()-1);
		
		if(lastRow.size()==0||(lastRow.size()>0&&lastRow.get(lastRow.size()-1).equals("NL"))){
			operRow=new LinkedList();
			this.rows.add(operRow);
		}else{
			operRow=lastRow;
		}
		operRow.add(o);
		rcIdx[0]=rows.indexOf(operRow);
		rcIdx[1]=operRow.indexOf(o);
		return rcIdx;
	}
	
	/** 对齐方式 */
	private int alignment=AIGNMENT_CENTER;
	
	/** 对齐居中 */
	public final static int AIGNMENT_CENTER=0;
	
	/** 对齐向左 */
	public final static int AIGNMENT_LEFT=1;
	
	/** 对齐向右 */
	public final static int AIGNMENT_RIGHT=2;
	
	/** alignments */
	private Map alignments=new HashMap();
	/** alignmentsComponent */
	private Map alignmentsComponent=new HashMap();
	/** alignmentsCol */
	private Map alignmentsCol=new HashMap();
	/** setAlignment */
	public void setAlignment(int rowIdx,int colIdx,int alignment){ this.alignmentsCol.put(rowIdx+","+colIdx, alignment); }
	/** setAlignment */
	public void setAlignment(Component c,int alignment){ this.alignmentsComponent.put(c, alignment); }
	/** setAlignment */
	public void setAlignment(int colIdx,int alignment){ this.alignmentsCol.put(colIdx, alignment); }
	
	/* (non-Javadoc) @see org.nobject.common.swing.g.GLayout#layoutContainer(java.awt.Container) */
	public void layoutContainer(Container parent) {
		int lenRows=rows.size();
		if(lenRows==0) return;
		int startX=0,startY=0;
		int rowMaxHeight=0;
		for (int idxRow = 0; idxRow < lenRows; idxRow++) {
			List cols=(List)rows.get(idxRow);
			for (int idxCol = 0;idxCol < cols.size(); idxCol++) {
				Object o=cols.get(idxCol);
				if(o.equals(NL)){
					startX=0;
					startY+=rowMaxHeight;
					rowMaxHeight=0;
					
				//多组件
				}else if(o.getClass().isArray()){
					Component [] cs=(Component [])o;
					
					int conpositW=0,conpositH=0;
					
					//格内间距
					int girdMargin=this.margin;
					if(this.margins.get(idxRow+","+idxCol)!=null) girdMargin=(Integer)this.margins.get(idxRow+","+idxCol);
					
					//计算总长
					for (int i = 0; i < cs.length; i++) {
						Component c=cs[i];
						conpositW+=c.getPreferredSize().width+this.hgap*2+girdMargin*2;
						conpositH=Math.max(conpositH,  c.getPreferredSize().height+this.vgap*2);
					}
					
					//格宽
					int girdWidth=conpositW;
					if(this.widthsCol.get(idxCol)!=null) girdWidth=(Integer)this.widthsCol.get(idxCol);
					if(this.widths.get(idxRow+","+idxCol)!=null) girdWidth=(Integer)this.widths.get(idxRow+","+idxCol);
					if(this.widthsComponent.get(cs)!=null) girdWidth=(Integer)this.widthsComponent.get(cs);
					
					//对齐方式
					int align=alignment;
					if(alignmentsCol.get(idxCol)!=null) align=(Integer)alignmentsCol.get(idxCol);
					if(alignments.get(idxRow+","+idxCol)!=null) align=(Integer)alignments.get(idxRow+","+idxCol);
					if(alignmentsComponent.get(cs)!=null) align=(Integer)alignmentsComponent.get(cs);
					
					//设置子组件坐标
					for (int i = 0; i < cs.length; i++) {
						int x=0;
						int y=0;
						int w=cs[i].getPreferredSize().width;
						int h=cs[i].getPreferredSize().height;
						
						switch (align) {
							case AIGNMENT_CENTER:	x=startX+(i==0?((girdWidth-conpositW)/2+hgap):0)+(i>0?margin:0);break;
							case AIGNMENT_LEFT:		x=startX+(i==0?hgap:0)+(i>0?margin:0);							break;
							case AIGNMENT_RIGHT:	x=startX+(i==0?(girdWidth-conpositW-hgap):0)+(i>0?margin:0);	break;
						}
						//y
						y=startY+vgap;
						
						//设置坐标
						Rectangle  r=new Rectangle(x,y,w,h);
						cs[i].setBounds(r);
						
						rowMaxHeight=Math.max(rowMaxHeight,h+this.vgap*2);
						startX=x+w+hgap*2+(i>=0?margin:0);
					}
				
				//单个组件
				}else if(o instanceof Component){
					Component c=(Component)o;
					
					//计算坐标
					int x=startX+hgap;
					int y=startY+vgap;
					int w=c.getPreferredSize().width;
					int h=c.getPreferredSize().height;
					
					//格宽
					int girdWidth=w;
					if(this.widthsCol.get(idxCol)!=null) girdWidth=(Integer)this.widthsCol.get(idxCol);
					if(this.widths.get(idxRow+","+idxCol)!=null) girdWidth=(Integer)this.widths.get(idxRow+","+idxCol);
					if(this.widthsComponent.get(c)!=null) girdWidth=(Integer)this.widthsComponent.get(c);
					
					int align=alignment;
					if(alignmentsCol.get(idxCol)!=null) align=(Integer)alignmentsCol.get(idxCol);
					if(alignments.get(idxRow+","+idxCol)!=null) align=(Integer)alignments.get(idxRow+","+idxCol);
					switch (align) {
						case AIGNMENT_CENTER:	x=startX+(girdWidth-w)/2+hgap;	break;
						case AIGNMENT_LEFT:		x=startX+hgap;					break;
						case AIGNMENT_RIGHT:	x=startX+girdWidth-w-hgap;		break;
					}
					
					Rectangle  r=new Rectangle(x,y,w,h);
					
					//设置坐标
					c.setBounds(r);
					
					
					//保存记录
					rowMaxHeight=Math.max(rowMaxHeight,  h+this.vgap*2);
					startX+=girdWidth;
				}
			}
			
		}
	}
	
	/** widthsCol*/
	private Map widthsCol=new HashMap();
	/** 设置宽度 */
	public void setWidth(int idxCol,int width){ widthsCol.put(idxCol, width);}
	
	/**widthRowCol*/
	private Map widths=new HashMap();
	/** 设置宽度 */
	public void setWidth(int idxRow,int idxCol,int width){widths.put(idxRow+","+idxCol, width);}
	
	/** widthsComponent */
	private Map widthsComponent=new HashMap();
	/** 设置宽度 */
	public void setWidth(Component c,int width){ widthsComponent.put(c, width); }
	
	
	
	/** setHgap */
	public void setHgap(int hgap) {
		this.hgap = hgap;
	}

	/** setVgap */
	public void setVgap(int vgap) {
		this.vgap = vgap;
	}

	/** 其它实现 */
	public void addLayoutComponent(String name, Component comp) {}
	public Dimension minimumLayoutSize(Container parent) {return null;}
	public Dimension preferredLayoutSize(Container parent) {return null;}
	public void removeLayoutComponent(Component comp) {}



}
